﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
using FluentValidation;
using FluentValidation.Results;
using RedeSocial.DataAccess;
using System.Data.Entity.Infrastructure;
using RedeSocial.ViewModels.Interfaces;
namespace RedeSocial.ViewModels
{
	[Serializable]
	public abstract class BaseViewModel : IBaseViewModel
	{
		#region fields...
		//private RedeSocialEntities _dataContext;
		private Language _defaultLanguage;
		private IValidator _fluentValidator;
		private ValidationResult _validationResult;
		#endregion
		#region properties...
		///// <summary>
		///// Gets or sets the entity framework data context that this view model will use.
		///// </summary>
		///// <value>
		///// The view model entity framework data context.
		///// </value>
		//public RedeSocialEntities DataContext
		//{
		//    get
		//    {
		//        return _dataContext;
		//    }
		//    set
		//    {
		//        _dataContext = value;
		//        NotifyPropertyChange("DataContext");
		//    }
		//}
		/// <summary>
		/// Gets or sets the default language.
		/// </summary>
		/// <value>
		/// The default language.
		/// </value>
		public Language DefaultLanguage
		{
			get
			{
				return _defaultLanguage;
			}
			set
			{
				_defaultLanguage = value;
				NotifyPropertyChange("DefaultLanguage");
			}
		}

		/// <summary>
		/// Gets or sets the fluent validation.
		/// </summary>
		/// <value>The fluent validation.</value>
		public IValidator FluentValidator
		{
			get
			{
				return _fluentValidator;
			}
			set
			{
				_fluentValidator = value;
				NotifyPropertyChange("FluentValidator");
			}
		}
		/// <summary>
		/// Gets or sets the validation result.
		/// </summary>
		/// <value>The validation result.</value>
		public ValidationResult ValidationResult
		{
			get
			{
				return _validationResult;
			}
			set
			{
				_validationResult = value;
				NotifyPropertyChange("ValidationResult");
			}
		}

		/// <summary>
		/// Checks if the entity is valid.
		/// For the entity to be valid all the defined rules must evaluate to true.
		/// </summary>
		/// <returns>True if all rules evaluate to True, otherwise False.</returns>
		public bool IsValid()
		{
			bool flag = Validate();
			if (!flag)
				foreach (var error in ValidationResult.Errors)
					NotifyPropertyChange(error.PropertyName);

			return flag;
		}

		#endregion
		#region methods...
		/// <summary>
		/// Validates this instance using FluentValidation.
		/// </summary>
		public bool Validate()
		{
			if (FluentValidator == null)
				return true;

			this.ValidationResult = FluentValidator.Validate(this);
			NotifyPropertyChange("Error");
			NotifyPropertyChange("ValidationResult");
			NotifyPropertyChange("IsValid");
			return this.ValidationResult.IsValid;
		}

		//protected string GetResource(string code)
		//{
		//    if (DataContext != null)
		//        return DataContext.ResourceLanguages.Where(rl => rl.Resource.Code == code).Select(rl => rl.Value).FirstOrDefault();
		//    else
		//        return string.Empty;

		//}
		#endregion

		#region INotifyPropertyChanged Members

		public event PropertyChangedEventHandler PropertyChanged;

		/// <summary>
		/// Raises the PropertyChangedEvent.
		/// </summary>
		/// <param name="propertyName">Name of the property that changed.</param>
		protected void NotifyPropertyChange(string propertyName)
		{
			if (PropertyChanged != null)
				PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
		}
		#endregion

		#region IDataErrorInfo Members

		/// <summary>
		/// Gets the error message for the property with the given name.
		/// </summary>
		/// <param name="propertyName"></param>
		/// <returns></returns>
		public string this[string propertyName]
		{
			get
			{
				StringBuilder sb = new StringBuilder();
				if (ValidationResult == null || ValidationResult.IsValid)
					return string.Empty;
				foreach (var error in this.ValidationResult.Errors.Where(e => e.PropertyName.Equals(propertyName, StringComparison.CurrentCulture)))
					sb.AppendLine(error.ErrorMessage);
				return sb.ToString();
			}
		}

		/// <summary>
		/// Gets an error message indicating what is wrong with this View Model. 
		/// </summary>
		public string Error
		{
			get
			{
				StringBuilder sb = new StringBuilder();
				if (this.ValidationResult == null || this.ValidationResult.IsValid)
					return string.Empty;
				foreach (var error in this.ValidationResult.Errors)
					sb.AppendLine(error.ErrorMessage);
				return sb.ToString();
			}
		}
		#endregion
	}
}
